package com.chencq.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @comment: 反射工具类
 * @author chencq
 * @Email:hero901027@163.com
 */
public class ClassReflectUtil {
	private static final Logger  LOGGER = LoggerFactory.getLogger(ClassReflectUtil.class);

	
	private ClassReflectUtil() {
	}
	/**
	 * 根据类名反射创建对象
	 * @param name 类名
	 * @return 对象
	 * @throws Exception
	 */
	public static Object getInstance(String classname) {
		Object o = null;
		try {
			Class<?> cls = Class.forName(classname);
			o = cls.newInstance();
		} catch (ClassNotFoundException e) {
			 LOGGER.error("没有找Class", e);
		} catch (Exception e) {
			 LOGGER.error("实例化失败", e);
		}
		return o;
	}
	/**
	 * 反射调用对象的方法
	 * @param obj 对象
	 * @param methodName 方法名称
	 * @param paramType 参数类型 new Class[]{int.class,double.class}
	 * @param params 参数值 new Object[]{2,3.5}
	 * @return
	 * @throws Exception
	 */
	public static Object executeMethod(Object obj, String methodName, Class<?>[] paramTypes, Object[] params) {
		// 发现类型
		Class<?> cls = obj.getClass();
		Object val = null;
		try {
			// 发现方法
			Method method = cls.getDeclaredMethod(methodName, paramTypes);
			// 访问方法时,压制Java对访问修饰符的检查
			method.setAccessible(true);
		     val = method.invoke(obj, params);
		} catch (SecurityException e) {
			 LOGGER.error("反射安全限制",e);
		} catch (NoSuchMethodException e) {
			 LOGGER.error("没有找到对应的方法",e);
		} catch (IllegalArgumentException e) {
			 LOGGER.error("调用方法参数不正确",e);
		} catch (IllegalAccessException e) {
			 LOGGER.error("非法调用方法",e);
		} catch (InvocationTargetException e) {
			 LOGGER.error("调用方法内部异常",e);
		}
		return val;
	}
	/**
	 * 通过反射获取实体对象
	 * @param clazz
	 * @param request
	 * @return 实体对象
	 */
	public static Object getEnity(Class<?> clazz, HttpServletRequest request) {
		Object o = null;
		try {
			o = clazz.newInstance();
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);// 保护
				field.set(o, request.getParameter(field.getName()));
				field.setAccessible(false);
			}
		} catch (Exception e) {
			 LOGGER.error("获取实体对象失败", e);
		}
		return o;
	}
}
